package rabid;

import java.io.IOException;

import common.Constants;
import common.UserInteractionException;

/**
 * This class represents a query passed in by the user. It's really just 
 * a wrapper for a TermList with some info about the allowed query grammar.
 * 
 * @author Andrew Bernard
 */
public class Query {
  private TermList termList;
  private String queryString;
  
  protected class Result {
    public Index.DataHeader dataHeader;
    public int lineNum;
    public int lineFilter;
    public QueryWord[] lineWordMap;
    public String lineText;
    
    public Result(Index.DataHeader dataHeader, int lineNum, int lineFilter, QueryWord[] lineWordMap) {
      this.dataHeader = dataHeader;
      this.lineNum = lineNum;
      this.lineFilter = lineFilter;
      this.lineWordMap = lineWordMap;
    }
    
    public String toString() {
      return "<\"" + dataHeader.shortFileName + "\", " + (lineNum+1) + ", \"" + lineText +"\">";
    }
  }
  
  /**
   * Constructor. 
   * @param query
   * @throws UserInteractionException throws this exception if the query's grammar is invalid
   */
  public Query(String query) throws UserInteractionException, IOException {
    query = query.trim();
    QueryGrammar grammar = new QueryGrammar(query);
    if(grammar.isValid()) {
      termList = new TermList(query);
      queryString = query;
    }
    else
      throw new UserInteractionException(Constants.ERR_GRAMMAR);
  }
  
  /**
   * Applies the pattern of this query to the mapping of words.
   * For example:<br><br>
   * <pre>
   *    mapping1 = [true] [false] [true]<br>
   *    mapping2 = [true] [false] [false]<br>
   *    <br>
   *    If this object's query pattern was: WORD1 (WORD2 | WORD3)    
   *    then this method would return true for mapping1 and
   *    false for mapping2
   * </pre>   
   * @param mapping   an array of Word objects corresponding to a line in a file 
   * @return the value of this query's pattern applied to the mapping
   */
  public boolean evaluate(QueryWord[] mapping) {
    return termList.evaluate(mapping);
  }
  
  public String toString() {
    return queryString;
  }
}
